import 'dart:typed_data';
import 'package:usb_serial/usb_serial.dart';
import 'package:xsdk_flutter/xsdk/xsdk_flutter_package.dart';



/*
usb串口通信(usb/type-c连接硬件) ANDROID  如:电子秤(串口转usb)
适用没有root的android手机/平板使用
https://pub-web.flutter-io.cn/packages/usb_serial

https://github.com/altera2015/usbserial

一次只支持单台设备连接

dependencies:
  usb_serial: ^0.5.2

import 'package:usb_serial/usb_serial.dart';

在android清单文件中添加:
<intent-filter>
		<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
	</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
		android:resource="@xml/device_filter" />
注意:这里已使用xsdk_android的XActivity_AutoGetUSBDevicePermission_FlutterXSDKPlugin自动授权


 */


abstract class XUsbSerialUtils{

  //记录设备
  static final Set<XBaseDevice> usbSerialDeviceList={};

  /*
  1.初始化 ok(注意:不能在app中初始化,因为sp初始化没完成,导致获取设备记录为空)
  注意:
  1.1.如果使用多用户保存:
  则需要登录后更新用户组:XSharePreferencesUtils.saveString(XConstants.SP_UserGroup,XXX);
  然后再初始化;切换用户或company时,则需要重新初始化
  1.2.如果不启用多用户,则可在欢迎界面初始化;
   */
  static void init() async{

    if(!XFlutterUtils.isAndroid()){
      XLogUtils.printLog('---非 Android平台,不支持此USB库!');
      return;
    }

    usbSerialDeviceList.clear();

    //1.连接设备
    String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
    String connectDeviceJson=XSharePreferencesUtils.getString('$userGroup${XConstants.SP_UsbSerialDevicesList}');

    if(!XStringUtils.isEmpty(connectDeviceJson)){
      List<dynamic> list=XJsonUtils.json2List(connectDeviceJson);
      for(dynamic item in list){
        usbSerialDeviceList.add(XBaseDevice.fromJson(item));
      }
    }

    XLogUtils.printLog('---设备usbSerial记录数=${usbSerialDeviceList.length}');

  }


  //2.关闭
  static void disconnectUsbSerialDevice() async{
    try{
      if(XFlutterUtils.isAndroid()){
        _usbPort?.close();
      }
    }catch(e){
      //
    }

  }



  //3.搜索usb设备
  static void scanUsbSerialDevices(
      {
        required XFunctionNotifyScanFinish<UsbDevice> notifyScanFinish,
      }
      ){

    try{

      if(!XFlutterUtils.isAndroid()){
        XLogUtils.printLog('---非 Android平台,不支持此USB库!');
        return;
      }

      UsbSerial.listDevices().then(
              (List<UsbDevice> devices)
          {

            for(UsbDevice device in devices){
              // device.deviceName  usb路径
              // device.productName //设备名
              // device.manufacturerName 设备品牌
              XLogUtils.printLog('---usbDevice =${device.toString()}');
            }
            notifyScanFinish(devices);
          }
      ).catchError((e){
        XLogUtils.printLog('----scanUsbSerialDevices报错:$e');
      });


    }catch(e){
      XLogUtils.printLog('e: $e');
    }

  }


  //4.添加设备记录(确保已获得授权的设备),场景:在扫描列表中选中添加
  static bool addNoteUsbDevice(UsbDevice usbSerialDevice,String customType){
    XBaseDevice usbDevice=XBaseDevice();
    usbDevice.deviceName=usbSerialDevice.productName;
    usbDevice.deviceUUID=_getUsbDeviceUUID(usbSerialDevice);
    usbDevice.customType=customType;

    if(!usbSerialDeviceList.contains(usbDevice)){
      usbSerialDeviceList.add(usbDevice);

      String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
      XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbSerialDevicesList}',XJsonUtils.obj2Json(usbSerialDeviceList));

      return true;
    }else{
      XLogUtils.printLog('已存在设备记录');
    }

    return false;
  }

  //获得设备唯一id,(获得授权,否则usbDeviceDescription.serialNumber为空)
  static String _getUsbDeviceUUID(UsbDevice usbSerialDevice){
    return '${usbSerialDevice.manufacturerName},${usbSerialDevice.productName},${usbSerialDevice.serial},${usbSerialDevice.pid},${usbSerialDevice.vid}';
  }


  //5.更新记录设备
  static bool updateNoteUsbDevice(XBaseDevice device){

    for(XBaseDevice deviceItem in usbSerialDeviceList){
      if(deviceItem==device){
        deviceItem.deviceName=device.deviceName;
        deviceItem.nickName=device.nickName;
        deviceItem.brand=device.brand;
        deviceItem.isConnected=device.isConnected;
        deviceItem.isUserSelect=device.isUserSelect;
        deviceItem.isEnable=device.isEnable;
        deviceItem.customType=device.customType;
        deviceItem.isGBK=device.isGBK;
        deviceItem.isSocketShortConnect=device.isSocketShortConnect;

        deviceItem.scenes =device.scenes;
        deviceItem.printerPagerSize=device.printerPagerSize;
        deviceItem.serialNumber=device.serialNumber;

        deviceItem.printCommandType=device.printCommandType;
        deviceItem.printTypeName=device.printTypeName;
        deviceItem.printerDPI=device.printerDPI;
        deviceItem.printerLabelSizeWidth=device.printerLabelSizeWidth;
        deviceItem.printerLabelSizeHeight=device.printerLabelSizeHeight;

        String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
        XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbSerialDevicesList}',XJsonUtils.obj2Json(usbSerialDeviceList));

        return true;
      }
    }

    return false;

  }
  //6.1.删除记录设备
  static void removeNoteUsbDevice(XBaseDevice device){

    usbSerialDeviceList.remove(device);

    String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
    XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbSerialDevicesList}',XJsonUtils.obj2Json(usbSerialDeviceList));

  }
  //6.2.删除记录设备
  static void removeNoteUsbDeviceByCustomType(String customType){

    usbSerialDeviceList.removeWhere((XBaseDevice element){
      if(customType==element.customType){
        return true;
      }
      return false;
    });

    String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
    XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbSerialDevicesList}',XJsonUtils.obj2Json(usbSerialDeviceList));

  }


  static UsbPort? _usbPort;

  //7.连接和接收信息
  static void connectUsbSerialDevice(
      {
        required XBaseDevice device,
        XFunctionResultCallback<Uint8List>? callback,
      }
      ) async
  {

    try{

      if(XFlutterUtils.isAndroid()){


        if(_usbPort!=null){
          _usbPort!.close();
        }

        List<UsbDevice> devices = await UsbSerial.listDevices();

        if(devices.isEmpty){
          XLogUtils.printLog('---没有可用usb串口设备');
          return;
        }


        UsbDevice? findDevice;

        for(UsbDevice usbItem in devices){
          String deviceUUID=_getUsbDeviceUUID(usbItem);
          if(device.deviceUUID==deviceUUID){
            XLogUtils.printLog('---找到指定usb串口设备');
            findDevice=usbItem;
            break;
          }
        }


        if(findDevice==null){
          XLogUtils.printLog('---没有找到指定usb串口设备');
          return;
        }

        _usbPort = await findDevice.create();
        if(_usbPort==null){
          XLogUtils.printLog('---_usbPort==null');
          return;
        }

        bool openResult = await _usbPort!.open();

        XLogUtils.printLog('---连接usbSerial结果 = $openResult');
        if (!openResult) {
          return;
        }

        await _usbPort!.setDTR(true);
        await _usbPort!.setRTS(true);

        _usbPort!.setPortParameters(
            9600,
            UsbPort.DATABITS_8,
            UsbPort.STOPBITS_1,
            UsbPort.PARITY_NONE
        );

        // print first result and close port.
        _usbPort!.inputStream?.listen((Uint8List data) {
          //XLogUtils.printLog('---data= $data');
          if(callback!=null){
            callback(data);
          }
        });

      }

    }catch(e){
      XLogUtils.printLog('---usb serial connect 报错:${e.toString()}');
    }

  }


  //2.写入
  void writeBytes(Uint8List data) async{
    if(XFlutterUtils.isAndroid()){
      await _usbPort?.write(data);
    }
  }


}
